﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Serialization;

namespace Update
{
    /// <summary>
    /// 
    /// </summary>
    public class MainWindowViewModel
    {
        /// <summary>
        /// 业务实体
        /// </summary>
        public MainWindowMoelds PageMoeld {  get; set; }
        /// <summary>
        /// 
        /// </summary>
        public MainWindowViewModel()
        {
            PageMoeld=new MainWindowMoelds() { Loading="正在更新应用程序....",IsDouble=true};
            Lood();         
        }

        private async void Lood()
        {
            await Task.Delay(2000);
            PageMoeld.ProgressBarDescribe="正在获取更新信息...";
            string ServerupdateUir_ = ConfigurationManager.AppSettings["ServerupdateUir"];
            string GetinVersionformationUir_ = ConfigurationManager.AppSettings["GetinVersionformationUir"];
            string DownloadfileUir_ = ConfigurationManager.AppSettings["DownloadfileUir"];
            string version_ = ConfigurationManager.AppSettings["version"];
            string localPath= AppDomain.CurrentDomain.BaseDirectory+ "file";
            string data = "";//版本号
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    HttpResponseMessage response =await client.GetAsync(ServerupdateUir_);//获取最新版本号 可以用客户端传过来
                    if(response.IsSuccessStatusCode)
                    {
                         data = await response.Content.ReadAsStringAsync();
                        //获取更新信息
                        if (version_!= data)
                        {
                            if (Directory.Exists(localPath))
                            {
                                deletefile(localPath);
                            }                          
                            HttpResponseMessage response1 = await client.GetAsync(GetinVersionformationUir_ + data);
                            string VersionInfo_ = await response1.Content.ReadAsStringAsync();
                            VersionInfo versionInfo_ = Newtonsoft.Json.JsonConvert.DeserializeObject<VersionInfo>(VersionInfo_);
                            PageMoeld.ProgressBarDescribe = $"共有{versionInfo_.FilesNumber}个文件更新...";
                            int BarValue = 0;
                            foreach (var item in versionInfo_.Filedownloadaddress)
                            {
                                HttpResponseMessage response2 = await client.GetAsync(DownloadfileUir_ + item);
                                using (Stream stream = await response2.Content.ReadAsStreamAsync())
                                {
                                    if (Directory.Exists(localPath) == false)
                                    {
                                        Directory.CreateDirectory(localPath);
                                    }
                                    using (FileStream fileStream = new FileStream($"{localPath}\\{System.IO.Path.GetFileName(item)}", FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
                                    {
                                        byte[] buffer = new byte[8192];
                                        int bytesRead;
                                        long totalBytes = response.Content.Headers.ContentLength ?? -1;
                                        while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                        {
                                            await fileStream.WriteAsync(buffer, 0, bytesRead);
                                        }
                                    }
                                }
                                BarValue++;
                                PageMoeld.ProgressBarValue = (int)((float)BarValue / versionInfo_.Filedownloadaddress.Count * 100);
                            }
                            // 打开当前执行文件的配置文件
                            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

                            // 获取AppSettings设置
                            AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings");
                            appSettings.Settings["version"].Value = data;
                            // 保存配置文件的更改
                            config.Save(ConfigurationSaveMode.Modified);
                            ConfigurationManager.RefreshSection("appSettings");
                            PageMoeld.ProgressBarDescribe = "下载完成 正在更新应用程序..";

                        }
                    }
                       UpdateInfo updateInfo_ = xmlUpdateInfo(localPath);
                        string path_ = AppDomain.CurrentDomain.BaseDirectory.Replace("\\Update","");
                        if (updateInfo_ != null && updateInfo_.PublishType == 1)
                         DeleteFilesExceptExcludedFolders(path_, new string[] { "Update" });
                        if(updateInfo_ != null && updateInfo_.PublishType == 1)
                          await ExtractZip(localPath, path_, Updateprogress(""));
                        else
                        {
                           foreach (var item in updateInfo_.Dtls)
                           {
                             File.Delete($"{path_}{item.FilePath}");
                            if (item.FilePath.Contains("\\"))
                            {
                                ZipFile.ExtractToDirectory($"{localPath}\\{item.PackageName}", path_+ System.IO.Path.GetDirectoryName(item.FilePath));
                                continue;
                            }
                            ZipFile.ExtractToDirectory($"{localPath}\\{item.PackageName}",path_);
                           }
                        }
                   // string Startexe =System.IO.Path.GetFileName(updateInfo_.Dtls.Where(o=>o.FilePath.Contains(".exe")).FirstOrDefault().FilePath);
                    PageMoeld.ProgressBarDescribe = "更新完成...";
                    //deletefile(localPath);
                    try
                    {
                        Process.Start($"{path_}\\WpfApp1.exe", data);
                        App.Current.Shutdown();
                        return;
                    }
                    catch (Exception ex)
                    {
                        PageMoeld.ProgressBarDescribe = "更新已经完成,尝试自动打开失败";
                    }
                    await Task.Delay(2000);
                    App.Current.Shutdown();
                    return;

                }
                catch (Exception ex)
                {
                    PageMoeld.ProgressBarDescribe = "更新出错,请联系管理员 程序即将退出";
                }
                if(PageMoeld.ProgressBarDescribe.Contains("更新出错,请联系管理员 程序即将退出"))
                {
                    //deletefile(localPath);
                    await Task.Delay(2000);
                    App.Current.Shutdown();
                }
                
            }

            //PageMoeld.IsDouble = false;
        }
        /// <summary>
        /// 解压
        /// </summary>
        /// <param name="zipFilePath"></param>
        /// <param name="destinationFolder"></param>
        private async Task ExtractZip(string zipFilePath, string destinationFolder, IProgress<int> progress)
        {
            // 检查 ZIP 文件是否存在
            if (!Directory.Exists(zipFilePath))
            {
                PageMoeld.ProgressBarDescribe = "解压失败,源文件不存在";
                return;
            }
            await Task.Run(() =>
            {
                // 如果目标文件夹不存在，则创建它
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }
                try
                {
                    string[] files = Directory.GetFiles(zipFilePath, "*.zip", SearchOption.AllDirectories);

                    int totalFiles = files.Length;
                    int filesExtracted = 0;
                    UpdateInfo person = xmlUpdateInfo(zipFilePath);
                    foreach (var item in files)
                    {
                        string name = System.IO.Path.GetFileName(item);
                        UpdateInfoDtl updateInfo = person.Dtls.FirstOrDefault(o => o.PackageName == name);
                        if (updateInfo != null && updateInfo.FilePath.Contains("\\"))
                        {
                            ZipFile.ExtractToDirectory(item, $"{destinationFolder}\\{System.IO.Path.GetDirectoryName(updateInfo.FilePath)}");
                        }
                        else
                        {
                            ZipFile.ExtractToDirectory(item, destinationFolder);


                        }
                        // 更新进度
                        filesExtracted++;
                        int progressPercent = (int)((float)filesExtracted / totalFiles * 100);
                        progress?.Report(progressPercent);  // 更新进度
                    }
                }
                catch (Exception ex)
                {
                    PageMoeld.ProgressBarDescribe = $"解压失败 错误信息{ex.Message}\r";
                }
            });
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <returns></returns>
        private UpdateInfo xmlUpdateInfo(string lastfilepath)
        {
            // 先读取 XML 文件内容
            string xmlContent = File.ReadAllText(lastfilepath + "\\update.xml");

            // 创建 XmlSerializer 对象
            XmlSerializer serializer = new XmlSerializer(typeof(UpdateInfo));
            UpdateInfo updateInfoList;
            using (StringReader reader = new StringReader(xmlContent))
            {
                // 进行反序列化
                updateInfoList = (UpdateInfo)serializer.Deserialize(reader);
            }
            return updateInfoList;
        }
        private void DeleteFilesExceptExcludedFolders(string directoryPath, string[] excludeFolders)
        {
            try
            {
                // 获取目录中的所有文件和子目录
                var files = Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories).Where(o=>!o.Contains("Update"));

                // 删除所有文件，除非它们位于排除的文件夹中
                foreach (var file in files)
                {
                 File.Delete(file); // 删除文件
                }
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 更新进度条
        /// </summary>
        private IProgress<int> Updateprogress(string Content)
        {
            PageMoeld.ProgressBarDescribe = Content;
            var progress = new Progress<int>(percent =>
            {
                // 这里更新UI或者其他进度条
                PageMoeld.ProgressBarValue = percent;
            });
            return progress;
        }
        /// <summary>
        /// 清除文件
        /// </summary>
        /// <param name="localPath"></param>
        private void deletefile(string localPath)
        {
            //清除文件
            try
            {
                DirectoryInfo dirInfo = new DirectoryInfo(localPath);
                // 获取文件夹内的所有文件，但不包括子目录中的文件（如果你想递归删除子目录中的文件，请使用下面的递归方法）
                FileInfo[] files = dirInfo.GetFiles();
                foreach (FileInfo file in files)
                {
                    file.Delete(); // 删除文件
                }

            }
            catch (Exception ex)
            {

            }
        }
    }
}
